package org.zk.interceptor;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.zk.util.RedisUtil;

import java.util.Map;

public class CacheInterceptor implements MethodInterceptor {
    private RedisUtil redisUtil;
    private Long defaultCacheExpireTime;

    /**
     * 初始化读取不需要加入缓存的类名和方法名
     */
    public CacheInterceptor() {
        try {
            //加载过期时间设置
            defaultCacheExpireTime = 3600L;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Object value = null;

        //类名
        String targetName = invocation.getThis().getClass().getName();
        //方法名
        String methodName = invocation.getMethod().getName();

        Object[] arguments = invocation.getArguments();

        Map<String, Object> maps = (Map<String, Object>) arguments[0];

        String pageSize = String.valueOf(maps.get("pageSize"));
        String pageNum = String.valueOf(maps.get("pageNum"));

        Object[] args = {pageNum + ":" + pageSize};

        final String key = getCacheKey(targetName, methodName, args);

        try {
            //如果有，取出来
            if (redisUtil.exists(key)) {
                return redisUtil.get(key);
            }
            //如果没有，写入
            value = invocation.proceed();
            if (value != null) {
                final String tkey = key;
                final Object tval = value;

                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        redisUtil.set(tkey, tval, defaultCacheExpireTime);
                    }
                }).start();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


        return value;
    }

    /**
     * 创建缓存key
     *
     * @param targetName
     * @param methodName
     * @param args
     * @return
     */
    private String getCacheKey(String targetName, String methodName, Object[] args) {
        StringBuffer sbu = new StringBuffer();
        sbu.append(targetName).append("_").append(methodName);

        if ((args != null) && (args.length != 0)) {
            for (int i = 0; i < args.length; i++) {
                sbu.append("_").append(args[i]);
            }
        }

        return sbu.toString();
    }

    public RedisUtil getRedisUtil() {
        return redisUtil;
    }

    public void setRedisUtil(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }
}
